/**
 * 倒计时处理
 * @author luguoxiang
 * @date 2021-09-07
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import { onMounted, onUnmounted, Ref, ref, watch } from 'vue';
import { dateParse } from '../utils';

export interface CountdownOptions {
  value: string | Date | Number;
}

interface CountdownRef {
  /** 天数 */
  d: number;
  /** 小时 */
  h: number;
  /** 分钟 */
  m: number;
  /** 秒 */
  s: number;
  /** 计数，秒数 */
  count: number;
  /** 格式化后的文本 */
  text: string;
  /** 小时（固定两位） */
  hh: string;
  /** 分钟（固定两位） */
  mm: string;
  /** 秒（固定两位） */
  ss: string;
  /** 是否停止倒计时 */
  stopped: boolean;
}

/**
 * 使用倒计时
 * @param options 间隔（ms）
 */
export function useCountdown(options?: string | Date | Number | CountdownOptions) {
  const data = ref<CountdownRef>({
    d: null,
    h: null,
    m: null,
    s: null,
    count: null,
    text: '',
    hh: '',
    mm: '',
    ss: '',
    stopped: true,
  });

  let timer: any = null;

  function reset(config = options) {
    if (!config) {
      return;
    }
    if (typeof config === 'string' || typeof config === 'number' || config instanceof Date) {
      config = { value: config };
    }
    const { value } = config;
    if (!value) {
      return;
    }
    if (typeof value === 'number') {
      data.value.count = Number(value);
      clearInterval(timer);
      timer = setInterval(() => {
        if (data.value.count > 0) {
          data.value.count--;
          data.value.stopped = false;
        } else {
          data.value.count = 0;
          data.value.stopped = true;
          clearInterval(timer);
        }
        data.value.text = String(data.value.count);
      }, 1000);
    } else {
      // @ts-ignore
      const time = dateParse(value).getTime();
      clearInterval(timer);
      timer = setInterval(() => {
        const info = data.value;
        let t = Math.floor((time - new Date().getTime()) / 1000);
        info.stopped = t <= 0;
        if (info.stopped) {
          t = 0;
          clearInterval(timer);
        }
        info.count = t;
        info.s = t % 60;
        info.ss = info.s < 10 ? `0${info.s}` : String(info.s);
        t = Math.floor(t / 60);
        info.m = t % 60;
        info.mm = info.m < 10 ? `0${info.m}` : String(info.m);
        t = Math.floor(t / 60);
        info.h = t % 24;
        info.hh = info.h < 10 ? `0${info.h}` : String(info.h);
        info.d = Math.floor(t / 24);
        info.text = `${info.d}天${info.hh}时${info.mm}分${info.ss}秒`;
        // bind.value = info;
      }, 1000);
    }
  }

  watch(() => options, reset, { immediate: true, deep: true });

  onUnmounted(() => {
    clearInterval(timer);
  });

  return {
    data,
    reset,
  };
}

/**
 * 使用定时器
 * @param call 回调函数，返回 true 时停止监听
 * @param interval
 */
export function useInterval(call: Function, interval = 1000) {
  let timer: any = null;
  onMounted(() => {
    timer = setInterval(() => {
      if (call()) {
        clearInterval(timer);
      }
    }, interval);
  });
  onUnmounted(() => {
    clearInterval(timer);
  });
  return timer;
}

/**
 * 使用定时器
 * @param call 回调函数，返回 true 时停止监听
 * @param interval
 */
export function useTimeout(call: Function, interval: number) {
  let timer: any = null;
  onMounted(() => {
    timer = setTimeout(() => {
      if (call()) {
        clearTimeout(timer);
      }
    }, interval);
  });
  onUnmounted(() => {
    clearTimeout(timer);
  });
  return timer;
}
